// Generic function pump
// Copyright 2006 (C) Ralph Thomas

#include <ui/function_adapter.h>
#include <boost/bind.hpp>

#include <iostream>

namespace app {
	function_adapter_t::function_adapter_t( adobe::sheet_t& sheet, const function_t& f, const adobe::dictionary_t& dict ) : sheet_m( sheet ), func_m( f ), dict_m( dict ) {
		//
		// We need to go through the dictionary and create
		// binder adapters for things that look like names
		// or binders.
		//
		adobe::dictionary_t::const_iterator first = dict_m.begin();
		adobe::dictionary_t::const_iterator last = dict_m.end();
		for( ; first != last; first++ ) {
			//
			// This is just a regular value, store it. We even store it
			// if it was a binder, in case it doesn't get updated (and
			// thus inserted into values_m) before we need it.
			//
			values_m.set( first->first, first->second );
			//
			// If it is a binder, then make it so we can get it's value.
			//
			if( (first->second.type() == typeid(adobe::name_t)) ||
			    (first->second.type() == typeid(adobe::binder_ptr_t)) ) {
				//
				// Create a binder_helper to extract the
				// real values for us.
				//
				adobe::binder_helper_t* helper = new adobe::binder_helper_t( sheet_m );
				helper->initialize( first->second,
					boost::bind( &adobe::dictionary_set<adobe::value_t>, boost::ref(values_m), first->first, _1 ), 0 );
				binders_m.push_back( helper );
			}
		}
	}
	function_adapter_t::~function_adapter_t() {
		//
		// Release all of our binder helpers.
		//
		for( binder_list_t::iterator i = binders_m.begin(); i != binders_m.end(); i++ )
			delete *i;
	}
	void function_adapter_t::set( const adobe::value_t& ) {}
	void function_adapter_t::set_signals(
		const adobe::sheet_t::monitor_value_t&, 
		const adobe::sheet_t::monitor_active_t& ) {}
	void function_adapter_t::substitute( const adobe::name_t& name, const adobe::value_t& val ) {
		for( binder_list_t::iterator i = binders_m.begin(); i != binders_m.end(); i++ )
			(*i)->substitute( name, val );
	}
	void function_adapter_t::invoke() {
		if( func_m ) func_m( values_m );
	}
};

